Skip to content

Refactor: 문서 목록 CQRS Read Model 전환 및 Domain Event Outbox 추가#204

Merged
lunarbae628 merged 36 commits into
devfrom
staging
May 20, 2026
Merged

Refactor: 문서 목록 CQRS Read Model 전환 및 Domain Event Outbox 추가#204
lunarbae628 merged 36 commits into
devfrom
staging

Conversation

@lunarbae628
Copy link
Copy Markdown
Collaborator

@lunarbae628 lunarbae628 commented May 20, 2026

🛰️ Issue Number

🪐 작업 내용

문서목록 cqrs 전환

📚 Reference

✅ Check List

  • 코드가 정상적으로 컴파일되나요?
  • 테스트 코드를 통과했나요?
  • merge할 브랜치의 위치를 확인했나요?
  • Label을 지정했나요?

…스케이스 메서드화로 호출부에서의 의미 들어나게 변경

- flyway 마이그레이션 sql문 생성(originType 삭제)
 - Factory -> JobEnqueuer
 - DeleteService -> DeleteExecutor
 - MongoDeleteOutboxCreateService를 제거하고 JobEnqueuer에서 saveAndFlush를 직접 호출
 - 변경된 이름과 중복 충돌 처리 방식에 맞춰 테스트 수정
- 도메인 이벤트 저장용 outbox 엔티티와 마이그레이션을 추가
- outbox relay, lifecycle service, wake-up listener를 추가
- 로컬 dispatcher를 통해 문서 목록 projector로 이벤트를 전달하도록 구성
- 문서 목록 조회용 Mongo read model과 payload를 추가
- 신규 JPA/Mongo repository 패키지를 스캔 설정에 등록
- 문서 목록 projection payload를 이벤트 타입별 record로 분리
- DocListProjector가 이벤트 타입별 payload를 역직렬화하도록 변경
- DocListReadModel에 생성/제목/활동/썸네일/삭제 이벤트별 반영 메서드를 추가
- DocPayloadFactory를 추가해 이벤트 payload 생성 책임을 분리
- 문서 생성 트랜잭션에서 DOC_CREATED outbox 이벤트를 저장하도록 연결
- 문서 제목 변경 시 DOC_TITLE_CHANGED outbox 이벤트를 저장하도록 연결
- 제목 변경 단위 테스트에 outbox publish 검증을 추가
- @EnableAsync 설정을 AsyncConfig로 분리
- outbox wake-up listener가 전용 executor를 사용하도록 변경
- 트랜잭션 커밋 이후 이벤트만 처리하도록 fallbackExecution을 제거
- 브랜치 생성, 병합, 커밋 생성, 저장 수정, 썸네일 확정, 문서 삭제 흐름에서 문서 목록 read model 갱신용 domain event outbox를 발행 연결
- 브랜치가 save를 가진다는 현재 도메인 규칙에 맞춰 커밋 통합 테스트 fixture를 보정
- DocListProjector의 이벤트별 read model 반영과 eventId 기반 idempotency를 단위 테스트로 검증
- 오래된 DOC_DELETED 이벤트가 최신 read model 상태를 덮어쓰지 않도록 lastProjectedEventId 반영을 보정
- DomainEventOutboxRelay의 DONE/retry/FAILED 상태 전이를 통합 테스트로 검증
- relay, dispatcher, projector, Mongo read model까지 이어지는 DOC_CREATED projection 통합 테스트를 추가
- DocService를 DocCommandService로 분리하고 문서 목록/검색/그래프 조회를 DocQueryService로 이동
- 문서 목록/검색 응답을 DocListReadModel 기반으로 매핑하도록 변경
- 기존 SQL 목록 조립용 DocListAssembler를 제거하고 read model mapper를 추가
- command/query 분리에 맞춰 컨트롤러 및 테스트를 정리
- 컨트롤러 테스트의 MockMvc print 출력을 제거해 테스트 로그 노이즈를 줄임
- test/local/stg/prod 환경의 SQL 및 bind parameter 로그 레벨을 명시
- local 환경에서는 필요 시 환경변수로 SQL 로그를 켤 수 있도록 조정
- 문서 도메인 테스트를 api/app 단위와 통합 테스트 패키지로 정리
- DocQueryService 목록 응답에서 thumbnailObjectKey null/blank 처리 검증 추가
- thumbnailObjectKey가 있으면 CDN URL로 변환되는지 검증
- local 프로필에서 Mongo DB를 시작/종료 시 정리하는 cleanup 컴포넌트 추가
- test 프로필에서 테스트 DB 정리를 위한 cleanup 컴포넌트 추가
- 안전한 DB 이름(-local, -test)에 대해서만 drop 하도록 보호 로직 추가
- cleanup 동작을 검증하는 단위 테스트 추가
- 커밋 조회/검증 책임을 CommitReader로 분리
- 커밋 저장/삭제 책임을 CommitWriter로 분리
- CQRS QueryService와 혼동되는 기존 CommitQueryService 명명을 제거
- 브랜치 조회/검증 책임을 BranchReader로 분리
- 브랜치 생성/저장/삭제 책임을 BranchWriter로 분리
- CQRS QueryService와 혼동되는 기존 BranchQueryService 명명을 제거
- 저장 조회/검증 책임을 SaveReader로 분리
- 저장 생성/갱신 책임을 SaveWriter로 분리
- CQRS QueryService와 혼동되는 기존 SaveQueryService 명명을 제거
- 이미지 조회 전용 서비스를 ImageReader로 변경
- 썸네일 영속성 접근을 ThumbnailStore로 정리
- CQRS QueryService와 혼동되는 기존 QueryService 명명을 제거
- 기존 Doc 데이터를 batch 단위로 조회해 DocListReadModel을 초기 생성
- Mongo setOnInsert upsert로 기존 read model을 덮어쓰지 않도록 처리
- backfill profile에서 실행되는 one-off job과 테스트 설정 추가
- local backfill 실행 스크립트를 추가
- backfill profile에서 local initializer와 cleanup이 실행되지 않도록 조정
- backfill 실행 시 domain event relay bean 의존성은 유지하되 scheduler 실행은 지연
- 목록 조회에서 deleted=true read model이 제외되는지 검증
- 제목 검색 조회에서도 삭제된 read model이 제외되는지 검증
Refactor: 문서 목록 CQRS Read Model 전환 및 Domain Event Outbox 추가
@lunarbae628 lunarbae628 self-assigned this May 20, 2026
@lunarbae628 lunarbae628 merged commit 306bcf9 into dev May 20, 2026
4 checks passed
@lunarbae628
Copy link
Copy Markdown
Collaborator Author

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 306bcf99ed

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +77 to +78
domainEventOutboxPublisher.publish(DomainEventType.DOC_THUMBNAIL_CHANGED, AggregateType.DOC, docId,
DocPayloadFactory.thumbnailChanged(docId, image.getObjectKey(), ThumbnailStatus.READY));
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Project the pending thumbnail status

For a document receiving its first thumbnail, requestUpdate() changes the MySQL thumbnail status from EMPTY to PENDING, but the read model only receives an event after finalization with READY. Since document-list responses now come exclusively from this read model, list and search APIs continue reporting EMPTY throughout thumbnail generation instead of the PENDING status that the previous SQL-backed list exposed. Publish the status transition when the update is requested.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant